package game;

import java.awt.Color;
import java.awt.Graphics2D;

import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.util.LinkedList;

import collision.Collision;

import levels.*;
import loading.ImageLoader;
import main.*;
import math.Vector2D;
import editor.Level;
import entity.Attackable;
import entity.Entity;
import entity.building.Building;
import entity.humans.Builder;
import entity.humans.Helicopter;
import entity.humans.HumanCenter;
import entity.humans.Tank;
import entity.units.*;

import gamestate.*;
import user.Button;
import user.User;

public class InGame extends State
{
	private static final ImageLoader ui = new ImageLoader( "Images/mainUI.png" );
	
	private GameList list;
	
	private Level level;
	private PathFinder pf;
	private PathGrid pg;
	
	private Entity selected;
	
	private MiniMap miniMap;
	private Screen view;
	
	private LinkedList<Button> options;
	
	public InGame( StateStack ss, User user )
	{
		super( ss, user );
		
		list = new GameList();
		
		level = Level.load( "Levels/Valley.txt" );
		
		pf = new PathFinder( pg = new PathGrid( level ) );
		
		Builder b = new Builder( new Vector2D( 32 * 14, 32* 10 ), pf );
		b.setAsTrained();
		list.add( b );
		
		selected = null;

		view = new Screen( level.getWidth() * 32, level.getHeight() * 32 );
		
		miniMap = new MiniMap( list, new Vector2D( 8, 648 ), view, level.getWidth(), level.getHeight() );
		
		options = null;
	}
	
	public void update( double duration )
	{
		list.update( duration );
		
		Collision.fixAllDynamicEntityCollisions( list.getList() );
		
		if( getUser().keyIsPressed( KeyEvent.VK_ESCAPE ) )
		{
			System.exit( 0 );
		}
		
		if( getUser().keyIsPressed( KeyEvent.VK_UP ) ) 
		{
			view.move( new Vector2D( 0, -10 ) );
		}
		if( getUser().keyIsPressed( KeyEvent.VK_DOWN ) ) 
		{
			view.move( new Vector2D( 0, 10 ) );
		}
		if( getUser().keyIsPressed( KeyEvent.VK_LEFT ) ) 
		{
			view.move( new Vector2D( -10, 0 ) );
		}
		if( getUser().keyIsPressed( KeyEvent.VK_RIGHT ) ) 
		{
			view.move( new Vector2D( 10, 0 ) );
		}
		
		Vector2D mouse = getUser().getMousePos();
		if( mouse != null )
		{
			if( getUser().getButton() == 1 )
			{
				if( miniMap.mouseInMiniMap( mouse ) )
				{
					view.setCenter( miniMap.fromMiniMaptoWorld( mouse ) );
				}
				else if( selected instanceof Building && ((Building)selected).testOptions( mouse, list, pf ) )
				{
					//All is done
				}
				else
				{
					mouse.add( view.getPosition() );
					
					selected = list.select( mouse );
					
					if( selected instanceof Building )
						options = ((Building)selected).getOptions();
					else if( selected == null )
						options = null;
				}
			}
			else if( getUser().getButton() == 2 )
			{
				mouse.add( view.getPosition() );
				
				if( selected instanceof Worker )
				{
					Building b = new HumanCenter( PathGrid.fromWorldToWorldOnGrid( mouse ), pg );
					list.add( b );
					((Worker)selected).build( b );
				}
			}
			else if( getUser().getButton() == 3 )
			{
				if( miniMap.mouseInMiniMap( mouse ) )
				{
					mouse = miniMap.fromMiniMaptoWorld( mouse );
				}
				else 
					mouse.add( view.getPosition() );
				
				if( selected instanceof Worker )
				{
					Entity e = list.select( mouse );
					if( e instanceof Building && !((Building)e).isBuilt() )
					{
						((Worker)selected).build( (Building)e );
					}
					else
					{
						((Worker)selected).goTo( mouse );
					}
				}
				else if( selected instanceof Attacker )
				{
					Entity e = list.select( mouse );
					
					if( e instanceof Attackable )
					{
						((Attacker)selected).attack( (Attackable)e );
					}
					else
					{
						((Unit)selected).goTo( mouse );
					}
				}
				else if( selected instanceof Unit )
				{
					((Unit)selected).goTo( mouse );
				}
				else if( selected instanceof Building )
				{
					((Building)selected).setRallyPoint( mouse );
				}
			}
			
			getUser().doneWithMouse();
		}
	}
	
	public void render( Graphics2D g )
	{
		g.setTransform( AffineTransform.getTranslateInstance( -view.getPosition().getX(), -view.getPosition().getY() ) );
		
		level.render( 1, g );
		level.render( 2, g );
		
		list.render( g );

		level.render( 3, g );
		
		g.setTransform( AffineTransform.getTranslateInstance( 0, 0 ) );
		
		ui.draw( g, AffineTransform.getTranslateInstance( 0, 640 ) );
		miniMap.render( g );
		
		if( options != null )
		{
			for( Button b : options )
				b.render( g );
		}
		
		if( selected != null && selected instanceof Building )
		{
			((Building)selected).drawInformation( g );
		}
	}
}
